package com.xiaode.controller.app.selfStudyRoom;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import com.jfinal.aop.Before;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.redis.Redis;
import com.xiaode.common.constant.Const;
import com.xiaode.common.model.Camera;
import com.xiaode.common.model.MonitorClassroom;
import com.xiaode.common.model.MonitorClassroomUser;
import com.xiaode.common.model.NotifyLog;
import com.xiaode.common.model.Student;
import com.xiaode.common.model.UserAccount;
import com.xiaode.common.model.UserFaceLog;
import com.xiaode.exce.EnumError;
import com.xiaode.util.hikvision.HikvisionUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;

public class SelfStudyService {
	
//	private static final String HKTeacherG = "599d833d403b465d91b7bf234cc42f13";//老师组
	private static final String HKStudentG = "e8e82da1021547d58c22e6740e788323";//学生组
//	private static final String HKTestG = "1bd27164445d4e5882f2c4863ca97166";//测试组

	/**
	 * 获取监控点列表
	 */
	public Ret getMonitorClassroomList() throws Exception {
		List<MonitorClassroom> monitorClassroomList = MonitorClassroom.dao.findAll();
		return Ret.ok("monitorClassroomList", monitorClassroomList);
	}
	
	/**
	 *	获取某个教室摄像头监控流
	 */
	public Ret getPreviewURLs(Integer monitorClassroomId) throws Exception {
		List<Camera> cameraList = Camera.dao.find("SELECT * FROM camera WHERE monitor_classroon_id = ?", monitorClassroomId);
		for(Camera camera : cameraList) {
			String url = HikvisionUtil.getPreviewURLs(camera.getCameraCode());
			camera.put("url", url);
		}
		return Ret.ok("cameraList", cameraList);
	}

	/**
	 * 获取摄像头回放流
	 */
	public Ret getPlaybackURL(Integer cameraId, String beginTime, String endTime) throws Exception {
		Camera camera = Camera.dao.findById(cameraId);
		String url = HikvisionUtil.getPlaybackURLs(camera.getCameraCode(), beginTime, endTime);
		return Ret.ok("url", url);
	}
	
	/**
	 * 获取教室内的人数
	 * 此接口是轮询，后期时间充足可优化为，通过聊天服务器主动推送
	 */
	public Ret getRoomPeopleNum(Integer monitorClassroomId) throws Exception {
		List<MonitorClassroomUser> monitorClassroomUserList = MonitorClassroomUser.dao.find("SELECT * FROM monitor_classroom_user WHERE monitor_classroom_id = ? ORDER BY user_type", monitorClassroomId);
		for(MonitorClassroomUser monitorClassroomUser : monitorClassroomUserList) {
			Record accountInfo = Redis.use().hget(Const.user.AccountIdInfo, monitorClassroomUser.getAccountId());
			monitorClassroomUser.put("accountInfo", accountInfo);
		}
		return Ret.ok("monitorClassroomUserList", monitorClassroomUserList);
	}
	
	/**
	 * 上传人脸
	 * 全程只会有一个待审核
	 */
	@Before(Tx.class)
	public Ret uploadFace(Integer accountId, Integer userType, String faceBase64) throws Exception {
		UserFaceLog userFaceLog = UserFaceLog.dao.findFirst("SELECT * FROM user_face_log WHERE account_id = ? AND state = 1", accountId);
		if(BeanUtil.isEmpty(userFaceLog)) {
			userFaceLog = new UserFaceLog();
			userFaceLog.setAccountId(accountId);
			userFaceLog.setUserType(userType);
			userFaceLog.setFaceBase64(faceBase64);
			userFaceLog.setState(Const.faceState.UNAUDITED);
			userFaceLog.setUploadTime(LocalDateTime.now());
			userFaceLog.save();
		}else {
			userFaceLog.setAccountId(accountId);
			userFaceLog.setUserType(userType);
			userFaceLog.setFaceBase64(faceBase64);
			userFaceLog.setState(Const.faceState.UNAUDITED);
			userFaceLog.setUploadTime(LocalDateTime.now());
			userFaceLog.update();
		}
		UserAccount userAccount = UserAccount.dao.findFirst("SELECT id FROM user_account WHERE id = ?", accountId);
		userAccount.setFaceUploadTime(LocalDateTime.now());
		userAccount.setFaceState(Const.faceState.UNAUDITED);
		userAccount.setFaceLogId(userFaceLog.getId());
		userAccount.update();
				
		return Ret.ok();
	}

	/**
	 * 老师需要审核人脸的数量
	 */
	public Ret needExamineCount(Integer userId) throws Exception {
		//先查询老师绑定的学生
		List<Integer> studentIdList = Db.query("SELECT studentId FROM teacher_student WHERE teacherId = ? AND state = 2", userId);	
		//获取学生accountId
		List<Integer> accountIdList = new ArrayList<Integer>();
		for(Integer studentId : studentIdList){
			Student student = Redis.use().get(Const.user.Student + studentId);
			accountIdList.add(student.getAccountId());
		}
		Kv kv = Kv.create();
		if(accountIdList.size() > 0) {
			kv.set("accountIdList", accountIdList);
		}else {
			return Ret.ok("count", 0);
		}
		Integer count = Db.template("needExamineFaceCount", kv).queryInt();
		
		return Ret.ok("count", count);
	}
	
	/**
	 * 老师审核人脸列表
	 * 老师管理的学生
	 */
	public Ret studentFacePage(Integer userId, String states, Integer page, Integer limit) throws Exception {
		List<Integer> stateList = JSONUtil.toList(states, Integer.class);
		//先查询老师绑定的学生
		List<Integer> studentIdList = Db.query("SELECT studentId FROM teacher_student WHERE teacherId = ? AND state = 2", userId);	
		//获取学生accountId
		List<Integer> accountIdList = new ArrayList<Integer>();
		for(Integer studentId : studentIdList){
			Student student = Redis.use().get(Const.user.Student + studentId);
			accountIdList.add(student.getAccountId());
		}
		//分页获取
		Kv kv = Kv.create();
		if(accountIdList.size() > 0) {
			kv.set("accountIdList", accountIdList);
		}else {
			return Ret.fail().set("error", EnumError.NOT_BANGDING_STUDENT.getObj());
		}
		if(stateList.size() > 0) {
			kv.set("stateList", stateList);
		}
		Page<Record> recordPage = Db.template("findAccountIdByFaceStateAndId", kv).paginate(page, limit);//这里返回来的是账号id
		for(Record record : recordPage.getList()) {
			Record accountInfo = Redis.use().hget(Const.user.AccountIdInfo, record.getInt("id"));
			Student o = Redis.use().get(Const.user.Student + accountInfo.getInt("id"));
            //移除不需要的属性
            o.remove("salt","lastLoginTime","isDele","version","state","isMainland","lastLoginTimestamp","parent","example");
            record.put("student", o);
		}
		
		return Ret.ok("studentFacePage", recordPage);
	}

	/**
	 * 老师审核人脸
	 */
	@Before(Tx.class)
	public Ret examineFace(Integer faceLogId, Integer state, String reason) throws Exception {
		UserFaceLog userFaceLog = UserFaceLog.dao.findById(faceLogId);
		if(BeanUtil.isEmpty(userFaceLog)){
			return Ret.fail().set("error", EnumError.FACE_EXAMINE_NULL.getObj());
		}
		userFaceLog.setState(state);
		userFaceLog.setReason(reason);
		userFaceLog.setExamineTime(LocalDateTime.now());
		userFaceLog.update();
		//添加通知日志
		NotifyLog notifyLog = new NotifyLog();
		notifyLog.setNotifyType(Const.notifyType.FACE_EXAMINE);
		notifyLog.setEventId(userFaceLog.getId());
		notifyLog.setAccountId(userFaceLog.getAccountId());
		notifyLog.setAddTime(LocalDateTime.now());
		notifyLog.setReadState(Const.faceNotifyReadType.NOREAD);
		notifyLog.save();
		
		UserAccount userAccount = UserAccount.dao.findFirst("SELECT id,face_code,face_state FROM user_account WHERE id = ?", userFaceLog.getAccountId());
		if(state == Const.faceState.PASS) {
			//判断是更新还是新加
			Record record = Redis.use().hget(Const.user.AccountIdInfo, userFaceLog.getAccountId());
			if(StrUtil.isBlank(userAccount.getFaceCode())) {//新加
				String faceCode = HikvisionUtil.addition(record.getStr("name") + record.getInt("id"), userFaceLog.getFaceBase64(), HKStudentG);
				if(StrUtil.isEmpty(faceCode)) {
					return Ret.fail().set("error", EnumError.ADD_FACE_FAIL.getObj());
				}
				userAccount.setFaceCode(faceCode);
				userAccount.setFaceGroupCode(HKStudentG);
				userAccount.setFaceState(Const.faceState.PASS);
				userAccount.setFaceExamineTime(LocalDateTime.now());
				userAccount.update();
			}else {//更新
				Boolean updateition = HikvisionUtil.updateition(userAccount.getFaceCode(), userFaceLog.getFaceBase64());
				if(!updateition) {
					return Ret.fail().set("error", EnumError.SYSTEM_ERROR.getObj());
				}
				userAccount.setFaceState(Const.faceState.PASS);
				userAccount.setFaceExamineTime(LocalDateTime.now());
				userAccount.update();
			}
		}else {
			userAccount.setFaceState(Const.faceState.NOPASS);
			userAccount.setFaceExamineTime(LocalDateTime.now());
			userAccount.update();
		}
		
		
		return Ret.ok();
	}

	/**
	 * 查看审核详情
	 */
	public Ret examineInfo(Integer accountId, Integer userType, Integer faceLogId) throws Exception {
		if(userType == Const.UserType.student) {
			UserFaceLog userFaceLog = UserFaceLog.dao.findFirst("SELECT * FROM user_face_log WHERE id = ? AND account_id = ?", faceLogId, accountId);
			return Ret.ok("userFaceInfo",userFaceLog);
		}
		UserFaceLog userFaceLog = UserFaceLog.dao.findFirst("SELECT * FROM user_face_log WHERE id = ?", faceLogId);		
		return Ret.ok("userFaceInfo",userFaceLog);
	}

	/**
	  * 学生获取自己审核列表
	  */
	public Ret examineList(Integer accountId, Integer userType, Integer page, Integer limit) throws Exception {
		Page<UserFaceLog> userFaceLogPage = UserFaceLog.dao.paginate(page, limit, "SELECT state,reason,upload_time,examine_time", "FROM user_face_log WHERE account_id = ? AND user_type = ? ", accountId, userType);
		return Ret.ok("userFaceLogPage", userFaceLogPage);
	}
	
	
	
	
}

